package com.apobates.jforum2.troll.forum.biz.impl;

import com.apobates.jforum2.troll.forum.biz.BoardStatsService;
import com.apobates.jforum2.troll.forum.biz.dao.BoardStatsDao;
import com.apobates.jforum2.troll.forum.entity.BoardStats;
import com.apobates.jforum2.troll.regular.ForumActionEnum;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author xiaofanku
 * @since 20200513
 */
@Service
public class BoardStatsServiceImpl implements BoardStatsService{
    @Autowired
    private BoardStatsDao boardStatsDao;
    private final static Logger logger = LoggerFactory.getLogger(BoardStatsServiceImpl.class);

    @Override
    public Stream<BoardStats> getFillTodayTopices(int boardGroupId) {
        return foldTodayTopices(boardStatsDao.findAllByBoardGroup(boardGroupId));
    }
    
    @Override
    public Stream<BoardStats> getFillTodayTopicesForNotOrigin() {
        return foldTodayTopices(boardStatsDao.findAllForNotOriginBoard());
    }
    
    @Override
    public Stream<BoardStats> getFillTodayTopices(Set<Long> boardIdSet) {
        if (null == boardIdSet || boardIdSet.isEmpty()) {
            return Stream.empty();
        }
        return foldTodayTopices(boardStatsDao.findAllByBoardId(boardIdSet));
    }
    
    @Override
    public Stream<BoardStats> getAll() {
        return boardStatsDao.findAll();
    }
    
    @Override
    public Stream<BoardStats> getByBoardIdList(Set<Long> boardIdList) {
        if (null == boardIdList || boardIdList.isEmpty()) {
            return Stream.empty();
        }
        return boardStatsDao.findAllByBoardId(boardIdList);
    }
    
    @Override
    public Optional<BoardStats> getByBoard(long boardId) {
        return boardStatsDao.findOneByBoard(boardId);
    }

    /*
    @Override
    public Optional<BoardStats> getFillTodayByBoard(final long boardId) {
        Optional<BoardStats> s = getByBoard(boardId);
        return s.map(bs->{
            long todays = topicDao.findAllRecentByBoardSize(boardId, DateTimeUtils.getTodayEarlyMorning());
            return fillTodaysBoardStats(bs, todays);
        });
        return s;
    }*/

    @Override
    public Map<ForumActionEnum, Long> sumTopicAndPosts() {
        return boardStatsDao.sumTopicAndPosts();
    }
    //0.1:从话题移动中分离出来的事务
    @Transactional
    @Override
    public Optional<Boolean> balanceTopicPosts(long targetBoardId, long boardId, long postsSize)throws IllegalStateException {
        boardStatsDao.balanceTopicPosts(targetBoardId, boardId, postsSize); //1话题的内容
        return Optional.of(true);
    }
    //
    @Transactional
    @Override
    public Optional<Boolean> balanceTopic(long targetBoardId, long boardId)throws IllegalStateException {
        boardStatsDao.balanceTopic(targetBoardId, boardId); //1话题的内容
        return Optional.of(true);
    }
    //0.3:从话题发布中分离出来的事务
    @Transactional
    @Override
    public Optional<Boolean> updateRecentTopic(
            long boardId,
            long recentTopicId,
            String recentTopicTitle,
            long recentTopicMember,
            String recentTopicMemberNickname) {
        logger.error("[forum-api][SRV] start update boardstats recent topic");
        return boardStatsDao.updateTopic(
                boardId,
                recentTopicTitle,
                recentTopicId,
                LocalDateTime.now(),
                recentTopicMember,
                recentTopicMemberNickname);
    }
    //0.4:从回复分离出来的事务(更新版块的回复数量)
    @Transactional
    @Override
    public Optional<Boolean> updatePostsSize(long boardId, long recentTopicId, long recentPostsId) {
        logger.error("[forum-api][SRV] start update boardstats posts size");
        return boardStatsDao.updatePosts(boardId);
    }

    private Stream<BoardStats> foldTodayTopices(Stream<BoardStats> rs){
        /*
        Map<Long, Long> todayTopicesMap = topicDao.statsBoardTopicSize(DateTimeUtils.getTodayEarlyMorning(), DateTimeUtils.getTodayMidnight());
        return rs.map(bs->{
            long todays = 0L;
            try {
                todays = todayTopicesMap.getOrDefault(bs.getBoardId(), 0L);
            } catch (NullPointerException e) {}
            return fillTodaysBoardStats(bs, todays);
        });*/
        return rs;
    }

    private BoardStats fillTodaysBoardStats(BoardStats oldIns, long todays){
        BoardStats tmp = new BoardStats();
        tmp.setBoardId(oldIns.getBoardId());
        tmp.setVolumesId(oldIns.getVolumesId());
        tmp.setTopices(oldIns.getTopices());
        tmp.setPostses(oldIns.getPostses());
        tmp.setFavorites(oldIns.getFavorites());
        tmp.setRecentTopicTitle(oldIns.getRecentTopicTitle());
        tmp.setRecentTopicId(oldIns.getRecentTopicId());
        tmp.setRecentTopicDate(oldIns.getRecentTopicDate());
        tmp.setRecentTopicMemberId(oldIns.getRecentTopicMemberId());
        tmp.setRecentTopicMemberNickname(oldIns.getRecentTopicMemberNickname());
        tmp.setUpdateDate(oldIns.getUpdateDate());
        tmp.setTodayTopices(todays);
        return tmp;
    }
}